package com.csii.adhoc.dblink.serviceImpl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.csii.adhoc.JdbcTemplate.DataSourceConfig;
import com.csii.adhoc.JdbcTemplate.JdbcTemplateFactory;
import com.csii.adhoc.dblink.mapper.DbLinkMapper;
import com.csii.adhoc.dblink.service.DbLinkService;
import com.csii.adhoc.dblink.DbLinkConstant;
import com.csii.adhoc.dblink.DbLinkPo;
import com.csii.adhoc.exception.ParamValidityException;
import com.csii.adhoc.id.UidGenerator;
import com.csii.adhoc.util.ParamCheckUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;

/**
 * @description: 数据连接接口实现类
 * @author: panChuanJiang
 * @create: 2021-01-13 09:32
 */
@Service("dbLinkService")
@Slf4j
@Lazy(false)
public class DbLinkServiceImpl implements DbLinkService {

    @Resource
    private DbLinkMapper dbLinkMapper;
    @Autowired
    private JdbcTemplateFactory jdbcTemplateFactory;
    @Autowired
    private UidGenerator uidGenerator;

    @Override
    @Transactional
    public void dbLinkMaintain(DbLinkPo dbLinkPo, String optMode) {
            switch (optMode) {
            case DbLinkConstant.OPT_MODE_ADD:
                dbLinkPo.setCreatedBy(dbLinkPo.getUpdatedBy());
                insertOneDbLink(dbLinkPo);
                break;
            case DbLinkConstant.OPT_MODE_DELETE:
                deleteDbLinkByPrimaryKey(dbLinkPo.getConnId());
                break;
            case DbLinkConstant.OPT_MODE_UPDATE:
                updateDbLinkByPrimaryKey(dbLinkPo);
                break;
            case DbLinkConstant.OPT_MODE_TESTCONN:
                testConnAvailable(dbLinkPo);
                break;
            default:
                log.error("optMode值不合法:" + optMode);
                throw new ParamValidityException("optMode值不合法:" + optMode);
        }
    }

    @Transactional
    @Override
    public void insertOneDbLink(DbLinkPo dbLinkPo) {
        if (StringUtils.isEmpty(dbLinkPo.getConnId())) {
            dbLinkPo.setConnId(uidGenerator.getUID() + "");
        }
        if (StringUtils.isEmpty(dbLinkPo.getAbbrName())) {
            dbLinkPo.setAbbrName(dbLinkPo.getName());
        }
        if (StringUtils.isEmpty(dbLinkPo.getIp())) {
            dbLinkPo.setIp(dbLinkPo.getHost());
        }
        setUrl(dbLinkPo);
        dbLinkPo.setCreatedDt(dbLinkPo.getUpdatedDt());
        dbLinkMapper.insertOneDbLink(dbLinkPo);
    }

    @Transactional
    @Override
    public void updateDbLinkByPrimaryKey(DbLinkPo dbLinkPo) {
        if (ParamCheckUtils.checkStringEmpty(dbLinkPo.getConnId())) {
            throw new ParamValidityException("connId为空");
        }
        setUrl(dbLinkPo);
        dbLinkMapper.updateDbLinkByPrimaryKey(dbLinkPo);
        jdbcTemplateFactory.removeJdbcTemplate(dbLinkPo.getConnId());
    }

    @Transactional
    @Override
    public void deleteDbLinkByPrimaryKey(String connId) {
        if (ParamCheckUtils.checkStringEmpty(connId)) {
            throw new ParamValidityException("connId为空");
        }
        dbLinkMapper.deleteDbLinkByPrimaryKey(connId);
        jdbcTemplateFactory.removeJdbcTemplate(connId);
    }

    @Override
    public DbLinkPo selectDbLinkByPrimaryKey(String connId) {
        if (StringUtils.isEmpty(connId)) {
            return null;
        }
        return dbLinkMapper.selectDbLinkByPrimaryKey(connId);
    }

    @Override
    public IPage<DbLinkPo> selectPageDbLink(Page<DbLinkPo> page, DbLinkPo dbLinkPo) {
        return dbLinkMapper.selectPageDbLink(page, dbLinkPo);
    }

    @Override
    public List<DbLinkPo> selectListDbLink(DbLinkPo dbLinkPo) {
        if (dbLinkPo==null){
            dbLinkPo = new DbLinkPo();
        }
        return dbLinkMapper.selectPageDbLink(dbLinkPo);
    }

    private void testConnAvailable(DbLinkPo dbLinkPo) {
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        setUrl(dbLinkPo);
        BeanUtils.copyProperties(dbLinkPo, dataSourceConfig);
        if (!JdbcTemplateFactory.testConnConfigAvailable(dataSourceConfig)) {
            throw new ParamValidityException("连接信息不可用");
        }
    }

    private void setUrl(DbLinkPo dbLinkPo) {
        String host = dbLinkPo.getHost();
        String port = dbLinkPo.getPort().toString();
        String driver = dbLinkPo.getDriverClass();
        String dbName = dbLinkPo.getDbname();
        String type = dbLinkPo.getType();
        StringBuilder url = new StringBuilder();
        if ("oracle.jdbc.driver.OracleDriver".equals(driver)) {
            dbLinkPo.setDbtype("0");
            //jdbc:oracle:thin:@172.16.57.145:1521:kfdb
            url.append("jdbc:oracle:thin:@").append(host).append(":")
                    .append(port).append(":").append(dbName);
        } else if ("com.mysql.jdbc.Driver".equals(driver)) {
            dbLinkPo.setDbtype("2");
            //jdbc:mysql://127.0.0.1:3306/shiro?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
            url.append("jdbc:mysql://").append(host).append(":")
                    .append(port).append("/").append(dbName).append("?")
                    .append("characterEncoding=").append(type)
                    .append("&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai");
        } else if ("sunje.goldilocks.jdbc.GoldilocksDriver".equals(driver)) {
            dbLinkPo.setDbtype("3");
            //jdbc:goldilocks://172.16.57.124:22581/test
            url.append("jdbc:goldilocks://").append(host).append(":")
                    .append(port).append("/").append(dbName);
        }
        dbLinkPo.setUrl(url.toString());
    }
}
